Skip to content

improvement(setup): make k8s mode end somewhere usable, and show install progress - #5966

Closed
TheodoreSpeaks wants to merge 1 commit into
stagingfrom
improvement/k8s-portforward
Closed

improvement(setup): make k8s mode end somewhere usable, and show install progress#5966
TheodoreSpeaks wants to merge 1 commit into
stagingfrom
improvement/k8s-portforward

Conversation

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator

Summary

  • k8s mode now offers to port-forward at the end and runs it in the foreground, so a finished install actually leaves you on http://localhost:3000. The services are ClusterIP, so before this "Sim is ready" meant a healthy cluster and nothing listening on the host.
  • Realtime gets its own forward too (kubectl takes one resource per invocation), otherwise the editor's socket has nothing to connect to.
  • helm --wait no longer blocks behind a static spinner. helm runs asynchronously while the cluster is polled, so the spinner reports 3/3 pods ready · 1 starting and a slow image pull is distinguishable from a wedged install.
  • CronJob-owned pods are excluded from that count — the chart schedules a lot of them (36 on my running cluster) and they finish as Completed, which would swamp readiness for reasons unrelated to the install. Restarting pods are surfaced rather than hidden.

Type of Change

  • Improvement

Testing

Verified against a live kind cluster (kind-sim, release sim-dev):

  • the dual port-forward the wizard runs returns 200 on both :3000/api/health and :3002/health, and both children are killed on exit
  • with no forward, :3000 returns nothing — the gap this closes
  • the progress query reads 3/3 pods ready and correctly excludes 36 CronJob pods

Every setup script builds and bun run lint passes. No UI or migration files touched, so /cleanup and /db-migrate don't apply.

Stacked context: this is independent of #5964 (which touches compose/db/lifecycle/csp, not modes/k8s.ts), so the two don't conflict.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…all progress

Two things made k8s mode the least satisfying path.

The services are ClusterIP, so a successful install left nothing on :3000 — 'Sim is ready' was true about the cluster and useless to the user, who had to notice and run a port-forward by hand. Compose opens a browser and dev offers to start the server; k8s now offers the forward the same way and runs it in the foreground so Ctrl-C ends it. Realtime gets its own forward (kubectl takes one resource per invocation) or the editor socket fails; it is a child in the same process group, so the terminal's Ctrl-C reaches it, and it is killed explicitly when the app forward exits.

'helm --wait' then blocked for minutes with a single static spinner, so a slow image pull looked identical to a wedged install. Run helm asynchronously and poll the cluster, so the spinner reports '3/3 pods ready · 1 starting'. CronJob-owned pods are excluded: the chart schedules a lot of them (36 on a running cluster here) and they finish as Completed, which would swamp the count and make readiness jitter for reasons unrelated to the install. Restarting pods are surfaced too — a cold cluster restarts realtime while Postgres comes up, and a silent spinner made that look like nothing was happening.
@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Jul 25, 2026 8:39pm

Request Review

@cursor

cursor Bot commented Jul 25, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Changes are limited to the local k8s setup script (helm/kubectl UX); no runtime app, auth, or data paths are modified.

Overview
K8s setup wizard (scripts/setup/modes/k8s.ts) no longer sits on a static spinner while helm upgrade --install --wait runs. Helm is started with spawn and the install spinner is updated every few seconds from kubectl get pods, reporting counts like 3/3 pods ready and notes for pods that are starting or restarting. CronJob-owned pods are excluded from that tally so completed one-off jobs do not distort readiness.

When the release is healthy, the “Reach your cluster” note is expanded (open URL, logs, forward, tear down). The wizard then prompts to port-forward app (:3000) and realtime (:3002) in the foreground so ClusterIP services are reachable from the host, matching the dev-mode “start the server” flow.

Reviewed by Cursor Bugbot for commit 3052dcf. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Improves Kubernetes setup completion and progress reporting.

  • Runs Helm asynchronously while polling Kubernetes pod status for spinner updates.
  • Excludes Job-owned pods from readiness counts and surfaces starting or restarting workloads.
  • Offers foreground app and realtime port-forwards after installation.
  • Expands the post-install command reference for access, logs, pod inspection, and teardown.

Confidence Score: 3/5

This PR should not merge until failures from both port-forward processes are detected and propagated instead of allowing setup to report success with unreachable endpoints.

The newly added forwarding path discards the app command's exit status and never observes the realtime child's failure, so realistic port conflicts or Kubernetes connection failures produce false successful completion.

Files Needing Attention: scripts/setup/modes/k8s.ts

Important Files Changed

Filename Overview
scripts/setup/modes/k8s.ts Adds asynchronous Helm progress and dual port-forwarding, but forwarding failures are not propagated to the setup wizard.

Sequence Diagram

sequenceDiagram
  participant Wizard as Setup wizard
  participant Helm
  participant K8s as Kubernetes
  participant AppPF as App port-forward
  participant RTPF as Realtime port-forward
  Wizard->>Helm: upgrade --install --wait
  loop Every 3 seconds
    Wizard->>K8s: get pods
    K8s-->>Wizard: readiness and waiting states
  end
  Helm-->>Wizard: installation result
  Wizard->>RTPF: start :3002 forward
  Wizard->>AppPF: run :3000 forward in foreground
  AppPF-->>Wizard: process exits
  Wizard->>RTPF: terminate
Loading

Reviews (1): Last reviewed commit: "improvement(setup): make k8s mode end so..." | Re-trigger Greptile

Comment on lines +422 to +430
const realtime = spawn(
'kubectl',
[...scope, 'port-forward', `svc/${RELEASE}-realtime`, '3002:3002'],
{ stdio: 'ignore' }
)
p.log.step(`Forwarding ${APP_URL} (app) and :3002 (realtime) — Ctrl-C to stop`)
spawnSync('kubectl', [...scope, 'port-forward', `svc/${RELEASE}-app`, '3000:3000'], {
stdio: 'inherit',
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Port-forward failures report success

When either local port is occupied, the Kubernetes connection drops, or a target service is unavailable, the realtime child can exit without being observed and the app command's exit status is discarded, causing setup to announce that Sim is ready even though one or both endpoints are unreachable.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3052dcf. Configure here.

spawnSync('kubectl', [...scope, 'port-forward', `svc/${RELEASE}-app`, '3000:3000'], {
stdio: 'inherit',
})
realtime.kill()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Port-forward failures go unchecked

Medium Severity

offerPortForward claims app and realtime are forwarding, but never checks that either kubectl actually succeeded. Realtime uses stdio: 'ignore', so bind failures vanish, and the app spawnSync result is discarded. Setup then returns normally and the wizard can still announce Sim is ready with nothing reachable on :3000/:3002.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3052dcf. Configure here.

initialValue: true,
})
if (!forward) {
p.log.info(theme.muted('Skipped — run the forward command above when you want to reach it.'))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual forward omits realtime

Medium Severity

The “Reach your cluster” note and the skip message only document forwarding the app service, while this change’s own comment states realtime needs a separate forward or the editor socket fails. Declining the prompt or copying the listed command leaves :3002 unforwarded even though NEXT_PUBLIC_SOCKET_URL points there.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3052dcf. Configure here.

if (containers.includes('ContainerCreating') || containers.includes('PodInitializing'))
pulling++
if (containers.includes('CrashLoopBackOff') || containers.includes('ImagePullBackOff'))
crashing++

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Init pull failures not surfaced

Low Severity

podProgress only reads containerStatuses waiting reasons, so ImagePullBackOff / CrashLoopBackOff on the migrations init container never increment the “restarting” count. A cold install stuck on simstudioai/migrations tends to look like quiet “starting” / not-ready progress instead of the wedged pull the spinner is meant to expose.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3052dcf. Configure here.

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

Folded into #5964 — the k8s port-forward + install-progress commit (ccac475) now lives there, so it's one PR to review and merge instead of two stacked on the same wizard.

No code was dropped; the commit cherry-picked cleanly since it only touches scripts/setup/modes/k8s.ts, which #5964 doesn't.

@TheodoreSpeaks
TheodoreSpeaks deleted the improvement/k8s-portforward branch July 25, 2026 20:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant